package com.gopay.checkorder.service.impl.tpas;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.gopay.checkorder.manager.TpasOrderManager;
import com.gopay.checkorder.service.CheckTpasOrderService;
import com.gopay.common.constants.bank.BankOrderStatus;
import com.gopay.common.constants.bank.tpas.TpasMwaChargeConstants;
import com.gopay.common.constants.bank.tpas.TpasOrderStatus;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.constants.wallet.optype.Wallet01618OpType;
import com.gopay.common.cps.manager.order.CpsGeneralMainOrderQueryManager;
import com.gopay.common.domain.bank.tpas.TpasMessage;
import com.gopay.common.domain.bank.tpas.TpasOrder;
import com.gopay.common.domain.bank.tpas.TpasResult;
import com.gopay.common.domain.bank.tpas.mwa.OrderCards;
import com.gopay.common.domain.bank.tpas.mwa.OrderMessage;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.domain.cps.vo.CPSRequest;
import com.gopay.common.domain.cps.vo.CPSResponse;
import com.gopay.common.domain.cps.vo.CheckOrderResult;
import com.gopay.common.domain.cps.vo.InAccInfo;
import com.gopay.common.domain.cps.wallet.Wallet01611Vo;
import com.gopay.common.domain.cps.wallet.Wallet01612VO;
import com.gopay.common.domain.cps.wallet.Wallet01613Vo;
import com.gopay.common.domain.cps.wallet.Wallet01618VO;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.spring.SpringContextUtil;
import com.gopay.remote.cps.dispatch.CPSCallRemoteService;
import com.gopay.remote.eis.ofpay.TpasChargeInteractRemoteService;

@Service("checkWachgeOrderService")
public class CheckWachgeOrderServiceImpl implements CheckTpasOrderService {
    private final static Logger logger = LoggerFactory.getLogger("CHECK_ORDER");
    
    @Resource(name = "tpasOrderManager")
    private TpasOrderManager tpasOrderManager;
    @Resource(name = "cpsGeneralMainOrderQueryManager")
    protected CpsGeneralMainOrderQueryManager mainOrderQuery;
    @Resource(name="callCPS")
    protected CPSCallRemoteService callCPS;
    
	@Resource(name = "tpasChargeInteractRemoteService")
	private TpasChargeInteractRemoteService mobileTrafficRechargeRemoteService;
//    @Resource(name="callCPSUtil")
//    protected CallCPSUtil callCPSUtil;
    
    @Override
    public CheckOrderResult checkOrder(TpasOrder order, String autoCheck) {
        CheckOrderResult checkOrderResult = new CheckOrderResult(false);
        if (order == null || StringUtils.isBlank(order.getOrderId())) {
            checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5060);
            logger.error("bankOrder is null or orderId is null." + ToStringBuilder.reflectionToString(order, ToStringStyle.DEFAULT_STYLE));
            return checkOrderResult;
        }
        checkOrderResult.setOrderId(order.getOrderId());
        try {
            // 锁定银行流水记录
            if (tpasOrderManager.lock(order) == 0) {
                logger.error("CheckOrderProxy test1: ");
                checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5060);
                checkOrderResult.setErrMsg("bankOrder is unlock");
                logger.error(order.getOrderId() + " bankOrder is unlock.");
                return checkOrderResult;
            }

            // 自动发起对单时,对单次数+1(状态不等于'入账失败')
            if (StringUtils.equals(TpasOrderStatus.AUTO_CHECK_SUCCESS, autoCheck) && !StringUtils.equals(BankOrderStatus.ENTER_ACCOUNT_FIAL, order.getOrderStatus())) {
                order.setTotalCheckTimes(order.getTotalCheckTimes() + 1);
                tpasOrderManager.update(order);
            }
            
            if (StringUtils.equals(TpasOrderStatus.ENTER_ACCOUNT_FIAL, order.getOrderStatus()) || StringUtils.equals(TpasOrderStatus.FAIL_ACCOUNT_FIAL, order.getOrderStatus())) {
//                CpsGenMainOrder mainOrder = getMainOrder(order.getOrderId());
                InAccInfo accInfo = new InAccInfo();
                accInfo.setOrderId(order.getOrderId());
                accInfo.setRetCode(order.getOrderStatus());
                accInfo.setCardType(order.getProdCode());
                checkOrderResult.setAccInfo(accInfo);
                checkOrderResult.setSuccess(true);
                checkOrderResult.setBankFailure(StringUtils.equals(TpasOrderStatus.FAIL_ACCOUNT_FIAL, order.getOrderStatus()) ? true : false);
//            }else if(StringUtils.equals(TpasOrderStatus.PROCESS, order.getOrderStatus()) && IntTxnCd._01618.value.equals(order.getProdCode())){//add by zhoupeng 20170622
//            	InAccInfo accInfo = new InAccInfo();
//                accInfo.setOrderId(order.getOrderId());
//                accInfo.setRetCode(order.getOrderStatus());
//                accInfo.setCardType(order.getProdCode());
//                checkOrderResult.setAccInfo(accInfo);
//                checkOrderResult.setSuccess(true);
//            	TpasMessage base = new TpasMessage();
//            	base.setOrderId(order.getOrderId());
//            	TpasResult result = mobileTrafficRechargeRemoteService.queryOrderInfo(base);
//            	logger.info("视频会员卡进行中的数据调用OF查询结果result="+result);
//            	if(result.getDefaultModel() != null){
//            		OrderMessage orderMessage = (OrderMessage)result.getDefaultModel();
//            		if (TpasMwaChargeConstants.CHARGE_SUCCESS.equals(orderMessage.getRetCode())) {
//            			checkOrderResult.setBankFailure(false);// 下面转成true了
//            			List<OrderCards> cardsList = orderMessage.getCardsList();// 卡密
//            			if (cardsList != null && cardsList.size() == 1) {
//            				for (OrderCards orderCards : cardsList) {
//            					String cardPws = orderCards.getCardPws();
//            					checkOrderResult.setCardPws(cardPws);
//            				}
//            			}
//            		} else if (TpasMwaChargeConstants.CHARGE_FAIL.equals(orderMessage.getRetCode())) {
//            			checkOrderResult.setBankFailure(true);// 下面转成false了- -
//            		}else{
//            			checkOrderResult.setSuccess(false);	//如果是进行中 直接给false 等待下一个5分钟再查
//            		}
//            	}
            }else {
                // 继续对账
                String beanName = order.getIntrfaceChannelCode() + "-TPAS";
                if (false == SpringContextUtil.containsBean(beanName)) {
                    logger.error("spring bean does not exist: " + beanName);
                    checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6044);
                    return checkOrderResult;
                }
                CheckTpasOrderService checkOrderService = (CheckTpasOrderService) SpringContextUtil.getBean(beanName);
                checkOrderResult = checkOrderService.checkOrder(order, TpasOrderStatus.AUTO_CHECK_SUCCESS);
                logger.error("checkOrderResult: " + ToStringBuilder.reflectionToString(checkOrderResult));
            }

            if (checkOrderResult.isSuccess()) {
                 logger.info("充值订单 : " + order.getOrderId() + ",对账成功");
                // 入账
                if (!inAcct(checkOrderResult)) {
                     logger.info("充值订单 orderid: " + order.getOrderId() + ",入账通知失败，更新bis订单");
                    // 入账不成功，对单失败
                    checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
                    checkOrderResult.setErrMsg("enter account fail.");
                    checkOrderResult.setSuccess(false);
                    
                    // 入账失败,状态更新96
                    order.setOrderStatus(TpasOrderStatus.ENTER_ACCOUNT_FIAL);
                    if(checkOrderResult.isBankFailure())
                    	order.setOrderStatus(TpasOrderStatus.FAIL_ACCOUNT_FIAL);
                    order.setLastUpdTs(new Date());
                    tpasOrderManager.update(order);
                    logger.error("充值订单 orderid: "+order.getOrderId()+",status："+order.getOrderStatus()+",入账通知失败，更新bis订单成功!!!");
                    return checkOrderResult;
                }else{
                     logger.info("充值订单 orderid: " + order.getOrderId() + ",入账通知成功，更新bis订单");
                    // 对单成功
                     order.setOrderStatus(TpasOrderStatus.ORDER_FAIL);
                     if(!checkOrderResult.isBankFailure()){
                         order.setOrderStatus(TpasOrderStatus.AUTO_CHECK_SUCCESS);
                         order.setTranFinishTime(new Date());
                     }
                    order.setLastUpdTs(new Date());
                    tpasOrderManager.update(order);
                    logger.error("充值订单 orderid: "+order.getOrderId()+",status："+order.getOrderStatus()+",入账通知成功，更新bis订单成功!!!");
                }
            }
        }catch(Exception e){
        	logger.error("对单失败，orderid:" + order.getOrderId(), e);
        }finally{
        	// 解锁
        	tpasOrderManager.unlock(order);
        }
        
        return null;
    }

    private boolean inAcct(CheckOrderResult result) {
    	boolean flag = false;
        InAccInfo accInfo = result.getAccInfo();
        if (accInfo == null) {
            return false;
        }
        
        boolean success = result.isBankFailure() ? false : true;
        String transType = accInfo.getCardType();
        CPSResponse cpsres = null; 
        try {
            switch (transType) {
                case "01611":
                    Wallet01611Vo vo01611 = new Wallet01611Vo();
                    vo01611.setSuccess(success);
                    vo01611.setGopayOrderId(accInfo.getOrderId());
                    vo01611.setStep(1);
                    cpsres = callByVOTicket(vo01611);
                    break;
                case "01612":
                    Wallet01612VO vo01612 = new Wallet01612VO();
                    vo01612.setProcStatus(success);
                    vo01612.setGopayOrderId(accInfo.getOrderId());
                    vo01612.setOprStep("2");
                    cpsres = callByVOTicket(vo01612);
                    break;
                case "01613":
                    Wallet01613Vo vo01613 = new Wallet01613Vo();
                    vo01613.setSuccess(success);
                    vo01613.setGopayOrderId(accInfo.getOrderId());
                    vo01613.setStep(1);
                    cpsres = callByVOTicket(vo01613);
                    break;
                case "01618"://add by zhoupeng 20170619  01618
                    Wallet01618VO vo01618 = new Wallet01618VO();
                    vo01618.setRechargeKey(StringUtils.isNotBlank(result.getCardPws())?result.getCardPws():null);
                    vo01618.setSuccess(success);
                    vo01618.setGopayOrderId(accInfo.getOrderId());
                    vo01618.setStep(Wallet01618OpType.ORDER_PROCESS);
                    cpsres = callByVOTicket(vo01618);
                    break;
                default:
                    break;
                }
        } catch (Exception e) {
            logger.error(String.format("充值订单%s,对账通知error: ", accInfo.getOrderId()), e);
        }
        if (ProcCodeConstants.PROC_CODE_100S1000.equals(cpsres.getRespCode()) 
                || ProcCodeConstants.PROC_CODE_000S1000.equals(cpsres.getRespCode())) {
        	flag = true;
            logger.error(String.format("充值订单%s入账通知成功!!!!", accInfo.getOrderId()));
        }else{
            logger.error(String.format("充值订单%s入账通知失败!!!!", accInfo.getOrderId()));
        }
        return flag;
	}

	private CPSResponse callByVOTicket(Object v) throws GopayException {
		CPSResponse response = null;
		try {
            // 封装调用cps服务的请求baggage
            Map<String, Object> baggage = new HashMap<String, Object>();
            baggage.put("s", "0");
            baggage.put("t", "001");
            baggage.put("v", v);

            // 封装cps请求对象
            CPSRequest request = new CPSRequest();
            request.setSequence(System.currentTimeMillis());
            request.setReqData(baggage);

            // 调用cps服务
            response = callCPS.callCPS(request);

            // 校验调用序列值是否相同
            if (response.getSequence() != request.getSequence()) {
                throw new GopayException(ProcCodeConstants.PROC_CODE_100F3001);
            }

        } catch (Exception e) {
        	logger.error("通知cps异常！！！", e);
            throw new GopayException(ProcCodeConstants.PROC_CODE_100F3001);
        }
		return response;
	}

	/**
     * 获取订单信息
     * 
     * @param base
     * @return
     * @throws GopayException
     */
    protected CpsGenMainOrder getMainOrder(String orderId) throws GopayException {
        // 获取主订单表
        CpsGenMainOrder mainOrder = mainOrderQuery.get(orderId);
        if (mainOrder == null) {
            throw new GopayException(ProcCodeConstants.PROC_CODE_100E5041, "mainOrder is null");
        }

        return mainOrder;
    }

    
   

}
